<script lang="ts" setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';

import { useAccessStore } from '@vben/stores';

import { AiEditor } from 'aieditor';

import 'aieditor/dist/style.css';

defineOptions({
  name: 'AiEditor',
  inheritAttrs: false,
});
const props = defineProps({
  value: {
    type: String,
    default: '',
  },
  width: {
    type: [String, Number],
    default: '100%',
  },
  height: {
    type: [String, Number],
    default: '500px',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  editorConfig: {
    type: Object,
    default: () => {
      return {};
    },
  },
});
const emits = defineEmits(['update:value']);
const content = computed({
  get() {
    return props.value;
  },
  set(val: string) {
    emits('update:value', val);
  },
});
const divRef = ref();
let aiEditor: AiEditor | null = null;
// 添加标志位，用于区分更新来源
let isUpdatingFromOnChange = false;
const accessStore = useAccessStore();
const defaultUploadConfig: any = {
  allowBase64: false,
  uploadUrl: `${import.meta.env.VITE_GLOB_API_URL}/sys/fileInfo/upload`,
  uploadFormName: 'file', // 上传时的文件表单名称
  uploadHeaders: () => {
    const mHeaders = {
      Authorization: `Bearer ${accessStore.accessToken}`,
    };
    return mHeaders;
  },
  uploaderEvent: {
    onSuccess: (file: any, response: any) => {
      // 监听附件上传成功
      // 注意：
      // 1、如果此方法返回 false，则附件不会被插入到编辑器
      // 2、可以在这里返回一个新的 json 给编辑器
      return {
        errorCode: response.code,
        data: {
          // 附件配置
          href: response.data.fullUrl,
          // 附件配置
          fileName: file.name,
          // 图片配置
          alt: file.name,
          // 图片和视频配置
          src: response.data.fullUrl,
        },
      };
    },
  },
};
onMounted(() => {
  aiEditor = new AiEditor({
    element: divRef.value as Element,
    placeholder: '点击输入内容...',
    content: content.value,
    contentIsMarkdown: false,
    toolbarExcludeKeys: ['ai'],
    editable: props.disabled !== true,
    textSelectionBubbleMenu: {
      enable: false,
      items: ['Bold', 'Italic', 'Underline', 'Strike', 'code', 'comment'],
    },
    attachment: defaultUploadConfig,
    image: defaultUploadConfig,
    video: defaultUploadConfig,
    onChange: (editor) => {
      isUpdatingFromOnChange = true;
      content.value =
        editor.options.contentIsMarkdown === false
          ? editor.getHtml()
          : editor.getMarkdown();
          // 下一个tick重置标志位
      setTimeout(() => {
        isUpdatingFromOnChange = false;
      }, 0);
    },
    ...props.editorConfig,
  });
});
onUnmounted(() => {
  aiEditor && aiEditor.destroy();
});
watch(
  () => content.value,
  (newValue) => {
    // 如果是从onChange触发的更新，则跳过
    if (isUpdatingFromOnChange || !aiEditor) {
      return;
    }
    if (aiEditor?.options.contentIsMarkdown === false) {
      aiEditor?.setContent(newValue);
    } else {
      aiEditor?.setMarkdownContent(newValue);
    }
  },
);
watch(
  () => props.disabled,
  () => {
    if (props.disabled === true) {
      aiEditor?.setEditable(false);
    } else {
      aiEditor?.setEditable(true);
    }
  },
);
defineExpose({
  getAiEditor() {
    return aiEditor;
  },
});
</script>

<template>
  <div ref="divRef" :style="{ width, height }"></div>
</template>
<style lang="less">
aie-footer {
  display: none !important;
}
.aie-container {
  .tippy-box {
    // 对包含特定元素的 .tippy-content 应用 padding: 0
    .tippy-content:has(.aie-popover),
    .tippy-content:has(aie-bubble-text),
    .tippy-content:has(.aie-dropdown-container),
    .tippy-content:has(aie-bubble-image) {
      padding: 0;
    }
  }
}
</style>
